package com.yifushidai.api;

import com.alibaba.fastjson.JSONObject;
import com.yifushidai.entity.ApiUniqueMac;
import com.yifushidai.entity.SfzUpload;
import com.yifushidai.mapper.ApiUniqueMacMapper;
import com.yifushidai.service.SfzUploadService;
import com.yifushidai.utils.*;
import io.swagger.annotations.*;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import tk.mybatis.mapper.entity.Example;

import javax.imageio.ImageIO;
import java.awt.*;
import java.io.InputStream;
import java.util.Date;
import java.util.List;

@RestController
@Api(tags = "身份证上传")
@RequestMapping("/api/sfz")
public class SfzUploadController extends ApiBaseAction {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private SfzUploadService sfzUploadService;
    @Autowired
    private ApiUniqueMacMapper apiUniqueMacMapper;

    @ApiOperation(value = "查询身份证绑定（列表）")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "form", name = "mac", value = "联网设备MAC", required = true),
            @ApiImplicitParam(paramType = "form", name = "beginTime", value = "开始时间", required = false, dataType = "date-time"),
            @ApiImplicitParam(paramType = "form", name = "endTime", value = "结束时间", required = false, dataType = "date-time"),
    })
    @PostMapping("list")
    //传递对象推荐使用 ModelAttribute 注解
    public R list(@RequestParam String mac, Date beginTime, Date endTime) {
        ApiUniqueMac one = apiUniqueMacMapper.selectOne(ApiUniqueMac.builder().mac(mac).build());
        if (null == one) return R.error(ErrorCodeEnum.MAC_NULL);

        Example example = new Example(SfzUpload.class);

        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("mac", mac);
        if (beginTime != null) {
            criteria.andGreaterThanOrEqualTo("endTime", beginTime);
        }
        if (endTime != null) {
            criteria.andLessThanOrEqualTo("beginTime", endTime);
        }

        return R.ok().put(sfzUploadService.selectByExample(example));
    }

    @ApiOperation(value = "查询身份证绑定（详情）")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "path", name = "id", value = "ID", required = true),
    })
    @PostMapping("/detail/{id}")
    //PathVariable是Spring 的注解，对于这种简单的参数，就可以不用写ApiParam来描述接口参数。
    public R detail(@PathVariable Integer id) {
        return R.ok().put(sfzUploadService.selectByKey(id));
    }

    @PostMapping("/upload")
    @ApiOperation("添加身份证绑定")
    @ApiImplicitParams({
//            @ApiImplicitParam(paramType = "form", name = "faceImg", value = "正面图片", required = true, dataType = "file"),
//            @ApiImplicitParam(paramType = "form", name = "backImg", value = "反面图片", required = true, dataType = "file"),
            @ApiImplicitParam(paramType = "form", name = "mac", value = "联网盒mac", required = true),
            @ApiImplicitParam(paramType = "form", name = "beginTime", value = "开始时间", required = true, dataType = "date-time"),
            @ApiImplicitParam(paramType = "form", name = "endTime", value = "结束时间", required = true, dataType = "date-time"),
    })
    public R upload(@RequestPart("faceImg") MultipartFile faceImg, @RequestPart("backImg") MultipartFile backImg,
                    @RequestParam String mac, @RequestParam Date beginTime, @RequestParam Date endTime) throws Exception {
        if (endTime.getTime() <= beginTime.getTime() || endTime.getTime() <= new Date().getTime()) {
            return R.error("失效时间设置有误");
        }
        ApiUniqueMac one = apiUniqueMacMapper.selectOne(ApiUniqueMac.builder().mac(mac).build());
        if (null == one) return R.error(ErrorCodeEnum.MAC_NULL);
        if (!isImage(faceImg.getInputStream()) || !isImage(backImg.getInputStream())) {
            return R.error(ErrorCodeEnum.FILE_UPLOAD_FAIL);
        }

        JSONObject faceObj = AliyunOCRUtil.getOCR("face", faceImg);
        if (faceObj == null || !faceObj.getBoolean("success") || StringUtils.isBlank(faceObj.getString("num"))) {
            return R.error(ErrorCodeEnum.OCR_ERROR);
        }
        JSONObject backObj = AliyunOCRUtil.getOCR("back", backImg);
        if (backObj == null || !backObj.getBoolean("success")) {
            return R.error(ErrorCodeEnum.OCR_ERROR);
        }
        SfzUpload record = new SfzUpload();
        record.setMac(mac);
        record.setFaceImg(AliyunOSSUtil.getSfzUrl(mac, faceImg, "face", faceObj.getString("num")));
        record.setBackImg(AliyunOSSUtil.getSfzUrl(mac, backImg, "back", faceObj.getString("num")));
        record.setXm(faceObj.getString("name"));
        record.setXb(faceObj.getString("sex"));
        record.setMz(faceObj.getString("nationality"));
        record.setCs(faceObj.getString("birth"));
        record.setZz(faceObj.getString("address"));
        record.setGmsfzhm(faceObj.getString("num"));
        record.setQfjg(backObj.getString("issue"));
        record.setYxqsrq(backObj.getString("start_date"));
        record.setYxjzrq(backObj.getString("end_date"));
        record.setBeginTime(beginTime);
        record.setEndTime(endTime);

        //TODO 取消身份证超时自动删除
//        String key = "SFZ_" + record.getMac() + "_" + record.getGmsfzhm();
//        ValueOperations<String, SfzUpload> operations = redisTemplate.opsForValue();
//        operations.set(key, record);
//        redisTemplate.expireAt(key, record.getEndTime());

        return R.ok().put(sfzUploadService.saveNotNull(record));
    }

    @ApiOperation(value = "删除身份证绑定")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "path", name = "id", value = "ID", required = true),
    })
    @PostMapping("/delete/{id}")
    public R delete(@PathVariable Integer id) {
        return R.ok().put(sfzUploadService.deleteByExample(id));
    }

    private static boolean isImage(InputStream inputStream) {
        if (inputStream == null) {
            return false;
        }
        Image img;
        try {
            img = ImageIO.read(inputStream);
            return !(img == null || img.getWidth(null) <= 0 || img.getHeight(null) <= 0);
        } catch (Exception e) {
            return false;
        }
    }

    @ApiOperation("oss列表")
    @PostMapping("/getObjectList")
    public R getObjectList() {
        return R.ok().put(AliyunOSSUtil.getObjectList(AliyunOSSUtil.BUCKET_NAME1));
    }

    @ApiOperation("oss删除")
    @PostMapping("/deleteObject")
    public R deleteObject(@ApiParam(value = "文件key", required = true) @RequestParam String objectKey) {
        return R.ok().put(AliyunOSSUtil.deleteObject(objectKey));
    }

}
